home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / Sample Code / AppsToGo / DTS.Lib / AERequired.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-24  |  10.7 KB  |  394 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:        DTS.Lib
  5. ** File:        AERequired.c
  6. ** Written by:  Eric Soldan
  7. **
  8. ** Copyright © 1990-1991 Apple Computer, Inc.
  9. ** All rights reserved.
  10. **
  11. ** This code implements the required AppleEvents, specific to DTS.Lib.
  12. */
  13.  
  14. /* You may incorporate this sample code into your applications without
  15. ** restriction, though the sample code has been provided "AS IS" and the
  16. ** responsibility for its operation is 100% yours.  However, what you are
  17. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  18. ** after having made changes. If you're going to re-distribute the source,
  19. ** we require that you make it clear in the source that the code was
  20. ** descended from Apple Sample Code, but that you've made changes. */
  21.  
  22.  
  23.  
  24. /*****************************************************************************/
  25.  
  26.  
  27.  
  28. #include "DTS.Lib2.h"
  29. #include "DTS.Lib.protos.h"
  30.  
  31. #ifndef __GESTALTEQU__
  32. #include <GestaltEqu.h>
  33. #endif
  34.  
  35.  
  36.  
  37. /*****************************************************************************/
  38.  
  39.  
  40.  
  41. #define kTimeOutInTicks (60 * 30)    /* 30 second timeout. */
  42.  
  43. static pascal OSErr    DoAEOpenDocuments(AppleEvent *message, AppleEvent *reply, long refcon);
  44. static pascal OSErr    DoAEPrintDocuments(AppleEvent *message, AppleEvent *reply, long refcon);
  45. static pascal OSErr    DoAEQuitApplication(AppleEvent *message, AppleEvent *reply, long refcon);
  46. static OSErr        OpenDocEventHandler(AppleEvent *message, AppleEvent *reply, short mode);
  47.  
  48.  
  49.  
  50. /*****************************************************************************/
  51.  
  52.  
  53.  
  54. static AEHandler keywordsToInstall[] = {
  55.     { kCoreEventClass,        kAEOpenApplication,        (AEEventHandlerProcPtr)DoAEOpenApplication,        nil },
  56.     { kCoreEventClass,        kAEOpenDocuments,        (AEEventHandlerProcPtr)DoAEOpenDocuments,        nil },
  57.     { kCoreEventClass,        kAEPrintDocuments,        (AEEventHandlerProcPtr)DoAEPrintDocuments,        nil },
  58.     { kCoreEventClass,        kAEQuitApplication,        (AEEventHandlerProcPtr)DoAEQuitApplication,        nil }
  59.         /* The above are the four required AppleEvents. */
  60. };
  61.  
  62. #define kNumKeywords (sizeof(keywordsToInstall) / sizeof(AEHandler))
  63.  
  64. Boolean        gHasAppleEvents = false;
  65. Boolean        gHasPPCToolbox  = false;
  66. DescType    gAERequiredType;
  67.  
  68. extern TreeObjHndl    gWindowFormats;
  69. extern Boolean        gNoFinderPrint;
  70.  
  71.  
  72.  
  73. /*****************************************************************************/
  74.  
  75.  
  76.  
  77. extern Boolean        gQuitApplication, gNoDefaultDocument, gInBackground;
  78. extern short        gPrintPage;
  79.  
  80. extern Cursor        *gCursorPtr;
  81. extern OSType        gAppWindowType;
  82.  
  83.  
  84.  
  85. /*****************************************************************************/
  86. /*****************************************************************************/
  87.  
  88.  
  89.  
  90. /* Intializes AppleEvent dispatcher table for the required events.  It also
  91. ** determines if the machine is PPCBrowser and AppleEvent capable.  If so,
  92. ** the booleans gHasAppleEvents and gHasPPCToolbox are set true.  This function
  93. ** must be the first AppleEvents initialization DTS.framework function called, as the
  94. ** other functions depend on the booleans being set correctly. */
  95.  
  96. #pragma segment AppleEvents
  97. OSErr    InitRequiredAppleEvents(void)
  98. {
  99.     OSErr    err;
  100.     long    result;
  101.     short    i;
  102.  
  103.     gHasPPCToolbox  = (Gestalt(gestaltPPCToolboxAttr, &result) ? false : result != 0);
  104.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &result) ? false : result != 0);
  105.  
  106.     if (gHasAppleEvents) {
  107.  
  108.         for (i = 0; i < kNumKeywords; ++i) {
  109.  
  110.             if (!keywordsToInstall[i].theUPP)
  111.                 keywordsToInstall[i].theUPP = NewAEEventHandlerProc(keywordsToInstall[i].theHandler);
  112.  
  113.             err = AEInstallEventHandler(
  114.                 keywordsToInstall[i].theEventClass,    /* What class to install.  */
  115.                 keywordsToInstall[i].theEventID,    /* Keywords to install.    */
  116.                 keywordsToInstall[i].theUPP,        /* The AppleEvent handler. */
  117.                 0L,                                    /* Unused refcon.           */
  118.                 false                                /* Only for our app.       */
  119.             );
  120.             if (err) {
  121.                 HCenteredAlert(rErrorAlert, nil, gAlertFilterUPP);
  122.                 return(err);
  123.             }
  124.         }
  125.     }
  126.  
  127.     return(noErr);
  128. }
  129.  
  130.  
  131.  
  132. /*****************************************************************************/
  133.  
  134.  
  135.  
  136. /* This function opens a new DTS.framework document due to an AppleEvents request. */
  137.  
  138. #pragma segment AppleEvents
  139. pascal OSErr    DoAEOpenApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  140. {
  141. #ifndef __MWERKS__
  142. #pragma unused (message, reply, refcon)
  143. #endif
  144.  
  145.     FileRecHndl    frHndl;
  146.     OSErr        err;
  147.     short        i;
  148.     TreeObjHndl    wobj;
  149.     long        attr;
  150.  
  151.     gAERequiredType = 'oapp';
  152.  
  153.     gCursorPtr = nil;
  154.         /* Force re-calc of cursor region and cursor to use. */
  155.  
  156.     err = noErr;
  157.     if (gWindowFormats) {
  158.         for (i = (*gWindowFormats)->numChildren; i;) {
  159.             wobj = GetChildHndl(gWindowFormats, --i);
  160.             attr = mDerefWFMT(wobj)->attributes;
  161.             if (!(attr & kwRuntimeOnlyDoc)) {
  162.                 if (attr & kwAutoNew) {
  163.                     err = NewDocumentWindow(&frHndl, mDerefWFMT(wobj)->sfType, true);
  164.                     if (err) break;
  165.                 }
  166.             }
  167.         }
  168.     }
  169.     else {
  170.         if (!gNoDefaultDocument) {
  171.             err = NewDocument(&frHndl, gAppWindowType, true);
  172.             if (!err) {
  173.                 if (frHndl) {
  174.                     err = DoNewWindow(frHndl, nil, GetNextWindow(nil, 0), (WindowPtr)-1);
  175.                     if (err)
  176.                         DisposeDocument(frHndl);
  177.                 }
  178.             }
  179.         }
  180.     }
  181.  
  182.     gAERequiredType = 0;
  183.  
  184.     return(err);
  185. }
  186.  
  187.  
  188.  
  189. /*****************************************************************************/
  190.  
  191.  
  192.  
  193. /* This function opens existing DTS.framework documents due to an AppleEvents request. */
  194.  
  195. #pragma segment AppleEvents
  196. static pascal OSErr    DoAEOpenDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  197. {
  198. #ifndef __MWERKS__
  199. #pragma unused (refcon)
  200. #endif
  201.  
  202.     OSErr    err;
  203.  
  204.     gAERequiredType = 'odoc';
  205.  
  206.     gCursorPtr = nil;        /* Force re-calc of cursor region and cursor to use. */
  207.     err = OpenDocEventHandler(message, reply, 0);
  208.         /* The 0 means regular open document. */
  209.  
  210.     gAERequiredType = 0;
  211.  
  212.     return(err);
  213. }
  214.  
  215.  
  216.  
  217. /*****************************************************************************/
  218.  
  219.  
  220.  
  221. /* This function prints DTS.framework documents due to an AppleEvents request. */
  222.  
  223. #pragma segment AppleEvents
  224. static pascal OSErr    DoAEPrintDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  225. {
  226. #ifndef __MWERKS__
  227. #pragma unused (refcon)
  228. #endif
  229.  
  230.     short                openMode;
  231.     ProcessSerialNumber    cpsn, fpsn;
  232.     Boolean                procsSame;
  233.     OSErr                err;
  234.  
  235.     if (gNoFinderPrint) err = DoAEOpenDocuments(message, reply, refcon);
  236.     else {
  237.         gAERequiredType = 'pdoc';
  238.         gCursorPtr = nil;                /* Force re-calc of cursor region and cursor to use. */
  239.  
  240.         openMode = 1;
  241.         if (!AEInteractWithUser(kTimeOutInTicks, nil, nil))
  242.             ++openMode;
  243.  
  244.         GetCurrentProcess(&cpsn);        /* We may have been moved to the front. */
  245.         GetFrontProcess(&fpsn);
  246.         SameProcess(&cpsn, &fpsn, &procsSame);
  247.         gInBackground = !procsSame;
  248.  
  249.         err = OpenDocEventHandler(message, reply, openMode);
  250.             /* openMode is either 1 or 2, depending if user interaction is okay. */
  251.  
  252.         gAERequiredType = 0;
  253.     }
  254.  
  255.     return(err);
  256. }
  257.  
  258.  
  259.  
  260. /*****************************************************************************/
  261.  
  262.  
  263.  
  264. /* This function sets a quit flag so that DTS.framework will quit due to an
  265. ** AppleEvents request. */
  266.  
  267. #pragma segment AppleEvents
  268. static pascal OSErr    DoAEQuitApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  269. {
  270. #ifndef __MWERKS__
  271. #pragma unused (message, reply, refcon)
  272. #endif
  273.  
  274.     OSErr    err;
  275.  
  276.     gCursorPtr = nil;
  277.         /* Force re-calc of cursor region and cursor to use. */
  278.  
  279.     if (DisposeAllWindows()) {
  280.         gQuitApplication = true;
  281.         err = noErr;
  282.     }
  283.     else err = errAEEventNotHandled;
  284.         /* All windows didn't close because user cancelled the quit. */
  285.  
  286.     return(err);
  287. }
  288.  
  289.  
  290.  
  291. /*****************************************************************************/
  292.  
  293.  
  294.  
  295. /* Called when we recieve an AppleEvent with an ID of "kAEOpenDocuments".
  296. ** This routine gets the direct parameter, parses it up into little FSSpecs,
  297. ** and opens each indicated file.  It also shows the technique to be used in
  298. ** determining if you are doing everything the AppleEvent record is telling
  299. ** you.  Parameters can be divided up into two groups: required and optional.
  300. ** Before executing an event, you must make sure that you've read all the
  301. ** required events.  This is done by making an "any more?" call to the
  302. ** AppleEvent manager. */
  303.  
  304. #pragma segment AppleEvents
  305. static OSErr    OpenDocEventHandler(AppleEvent *message, AppleEvent *reply, short mode)
  306. {
  307. #ifndef __MWERKS__
  308. #pragma unused (reply)
  309. #endif
  310.  
  311.     OSErr        err;
  312.     OSErr        err2;
  313.     AEDesc        theDesc;
  314.     FSSpec        theFSS;
  315.     short        loop;
  316.     long        numFilesToOpen;
  317.     AEKeyword    ignoredKeyWord;
  318.     DescType    ignoredType;
  319.     Size        ignoredSize;
  320.     FileRecHndl    frHndl;
  321.     WindowPtr    docWindow;
  322.  
  323.     theDesc.dataHandle = nil;
  324.         /* Make sure disposing of the descriptors is okay in all cases.
  325.         ** This will not be necessary after 7.0b3, since the calls that
  326.         ** attempt to create the descriptors will nil automatically
  327.         ** upon failure. */
  328.  
  329.     err = AEGetParamDesc(message, keyDirectObject, typeAEList, &theDesc);
  330.     if (err)
  331.         return(err);
  332.  
  333.     if (!MissedAnyParameters(message)) {
  334.  
  335. /* Got all the parameters we need.  Now, go through the direct object,
  336. ** see what type it is, and parse it up. */
  337.  
  338.         err = AECountItems(&theDesc, &numFilesToOpen);
  339.         if (!err) {
  340.             /* We have numFilesToOpen that need opening, as either a window
  341.             ** or to be printed.  Go to it... */
  342.  
  343.             for (loop = 1; ((loop <= numFilesToOpen) && (!err)); ++loop) {
  344.                 err = AEGetNthPtr(        /* GET NEXT IN THE LIST...         */
  345.                     &theDesc,            /* List of file names.             */
  346.                     loop,                /* Item # in the list.             */
  347.                     typeFSS,            /* Item is of type FSSpec.         */
  348.                     &ignoredKeyWord,    /* Returned keyword -- we know.  */
  349.                     &ignoredType,        /* Returned type -- we know.     */
  350.                     (Ptr)&theFSS,        /* Where to put the FSSpec info. */
  351.                     sizeof(theFSS),        /* Size of the FSSpec info.         */
  352.                     &ignoredSize        /* Actual size -- we know.         */
  353.                 );
  354.                 if (err) break;
  355.  
  356.                 err = OpenDocument(&frHndl, &theFSS, fsRdWrPerm);
  357.                 if (err) break;
  358.  
  359.                 gPrintPage = mode;
  360.                     /* Open the window off-screen if we are printing.
  361.                     ** We use the gPrintPage global to flag this.  Normally, the
  362.                     ** gPrintPage global is to tell ImageDocument if we are imaging
  363.                     ** to the window or to paper.  We don't need it for this yet,
  364.                     ** as we can't image the document until it is opened.  DoNewWindow()
  365.                     ** uses gPrintPage as a flag to open the window off-screen, but
  366.                     ** visible, so that PrintMonitor can use the title of the window
  367.                     ** as the document name that is being printed. */
  368.  
  369.                 err = DoNewWindow(frHndl, &docWindow, GetNextWindow(nil, 0), (WindowPtr)-1);
  370.                 if (err)
  371.                     DisposeDocument(frHndl);
  372.                 else {
  373.                     if (gPrintPage) {
  374.                         err  = PrintDocument(frHndl, (mode == 2), (loop == 1));
  375.                         mode = 1;    /* No interaction mode (mode == 2) only valid
  376.                                     ** for the first printed document. */
  377.                         DisposeDocument(frHndl);
  378.                         DisposeAnyWindow(docWindow);
  379.                     }
  380.                 }
  381.                 gPrintPage = 0;
  382.                     /* Put the ImageDocument controlling global back to normal. */
  383.             }
  384.         }
  385.     }
  386.     DonePrinting();        /* Clean up after printing, if we did any. */
  387.  
  388.     err2 = AEDisposeDesc(&theDesc);
  389.     return(err ? err : err2);
  390. }
  391.  
  392.  
  393.  
  394.